package minimax;

import java.util.Iterator;
import java.util.Vector;




import problem.Heuristic;
import problem.logic;
import agents.AgentImpl;
import env.City;
import env.Move;
import env.World;

public class MoveNode_B {
	public World copiedWorld;
	public Move moveToHere;
	public Vector<MoveNode_B> sons;
	public MoveNode_B parent;
	public int cost_friend;
	public int cost_foe;
	public int node_cost;
	public int depth;
	public int moveToHereCost;
	public AgentImpl friend;
	public AgentImpl foe;

	public MoveNode_B(World world, Move moveToHere, MoveNode_B parent,  AgentImpl friend, AgentImpl foe) 
	{
		super();
		sons = new Vector<MoveNode_B>();
		this.copiedWorld = new World(world);
		this.moveToHere = moveToHere;
		moveToHereCost = copiedWorld.moveAgents(moveToHere);
		this.parent = parent;
		
		//TODO this may have to be replaced with copy
		this.friend=friend;
		this.foe=foe;
		
		
		if (parent==null)
		{
			cost_friend=0;
			cost_foe=0;
			depth=main.Main.cutoff;
//			moveToHere=Minimax_decide();
		}
		else
		{
			depth=parent.depth-1;
			cost_friend=parent.cost_friend;
			cost_foe=parent.cost_foe;
		}
	}

	public Move Minimax_decide() 
	{
		
		Vector<Move> possibleMoves = copiedWorld.possibleMoves(friend, copiedWorld.getCityByName(friend.currentCityName())); //add documentation
		Iterator<Move> it = possibleMoves.iterator();
		Move ans=null;
		int[] temp_cost={Integer.MIN_VALUE,Integer.MIN_VALUE};
		while (it.hasNext())
		{
			Move move = it.next();
			City friendCurrent = friend.current;
			City foeCurrent = foe.current;
			
			MoveNode_B new_moveNode = new MoveNode_B(copiedWorld, move, this, friend, foe);
			sons.add(new_moveNode);
			if(ans==null)
			{
				ans = move;
				temp_cost = new_moveNode.max_value(new int[]{Integer.MIN_VALUE,Integer.MIN_VALUE});
			}
			else
			{
				int[] new_cost = new_moveNode.max_value(new int[]{Integer.MIN_VALUE,Integer.MIN_VALUE});
				if(bigger(temp_cost,new_cost))
				{
					ans=new_moveNode.moveToHere;
					temp_cost=new_cost;
				}
			}
			friend.setCurrentCity(friendCurrent);
			foe.setCurrentCity(foeCurrent);
		}

	
			return ans;
	}

	private int[] max_value(int[] prune_cost) 
	{
		
		cost_foe+=moveToHereCost;
		
		if(depth==0)
			
//			return Heuristic.cooperativeHeuristic(copiedWorld, friend,foe);
			return new int[] {cost_friend,cost_foe};
//			return new int[] {Integer.MAX_VALUE,Integer.MAX_VALUE};
		if(copiedWorld.allDone())
			return new int[] {cost_friend,cost_foe};
		int temp_cost[]={Integer.MAX_VALUE,Integer.MAX_VALUE};
		Vector<Move> possibleMoves = copiedWorld.possibleMoves(friend, copiedWorld.getCityByName(foe.currentCityName())); //add documentation
		Iterator<Move> it = possibleMoves.iterator();
		while (it.hasNext())
		{
			Move move = it.next();
			City friendCurrent = friend.current;
			City foeCurrent = foe.current;
			MoveNode_B new_moveNode = new MoveNode_B(copiedWorld, move, this, foe, friend);
			sons.add(new_moveNode);
			int[] max_result = new_moveNode.max_value(temp_cost);
			friend.setCurrentCity(friendCurrent);
			foe.setCurrentCity(foeCurrent);
			if(bigger(temp_cost,max_result))
			{
				temp_cost=max_result;
			}
//			if(bigger(temp_cost,prune_cost))
//				return temp_cost;
		}
			
		//return Math.max(temp_cost,cost_friend-cost_foe+main.Main.noOpCost);
		return temp_cost;
	}
	private boolean bigger(int[] first,int[] second)
	{
		if(first[0]>second[0])
			return true;
		else
		{
			if(first[0]<second[0])
				return false;
			else
				return (first[1]>second[1]);
		}
	}
}
